package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    //切入点
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){
        log.info("开始进行自动填充");
    }

    //前置通知,在通知中进行赋值
/**
 * 在执行自动填充切点方法之前调用的方法
 * 根据方法上的AutoFill注解，自动填充实体类的创建时间和更新时间等信息
 *
 * @param joinPoint 切入点对象，包含执行的方法信息和传入的参数
 */
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint){
    // 获取方法签名
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    // 获取方法上的AutoFill注解
    AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);
    // 获取方法参数
    Object[] args = joinPoint.getArgs();
    // 获取第一个参数作为实体对象
    Object entity = args[0];

    // 获取操作类型（插入或更新）
    OperationType operationType = annotation.value();
    // 获取当前时间和用户ID
    LocalDateTime now = LocalDateTime.now();
    Long currentId = BaseContext.getCurrentId();

    // 根据操作类型进行自动填充
    if (operationType == OperationType.INSERT) {
        try {
            log.info("开始INSERT自动填充");
            // 获取实体类中的set方法，并调用set方法为对应的数据赋值
            Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

            setCreateTime.invoke(entity,now);
            setCreateUser.invoke(entity,currentId);
            setUpdateTime.invoke(entity,now);
            setUpdateUser.invoke(entity,currentId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else if (operationType == OperationType.UPDATE) {
        try {
            log.info("开始UPDATE自动填充");

            // 获取实体类中的set方法，并调用set方法为对应的数据赋值
            Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

            setUpdateTime.invoke(entity,now);
            setUpdateUser.invoke(entity,currentId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
}
